package com.zhangzhan.gulimallmember.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangzhan.gulimallcommcon.constant.SourceType;
import com.zhangzhan.gulimallcommcon.util.PageUtils;
import com.zhangzhan.gulimallcommcon.util.Query;
import com.zhangzhan.gulimallcommcon.util.R;
import com.zhangzhan.gulimallmember.dao.MemberDao;
import com.zhangzhan.gulimallmember.entity.MemberEntity;
import com.zhangzhan.gulimallmember.entity.MemberLevelEntity;
import com.zhangzhan.gulimallmember.service.MemberLevelService;
import com.zhangzhan.gulimallmember.service.MemberService;
import com.zhangzhan.gulimallmember.tos.GiteeResTo;
import com.zhangzhan.gulimallmember.tos.GiteeUserInfoTo;
import com.zhangzhan.gulimallmember.tos.UserLoginTo;
import com.zhangzhan.gulimallmember.tos.UserRegisterTo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.zhangzhan.gulimallcommcon.exception.exception_enum.ExceptionEnum.*;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    private MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R enrollUser(UserRegisterTo to) {

        MemberEntity member = this.getOne(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getUsername, to.getUserName())
                .or().eq(MemberEntity::getMobile, to.getPhone()));
        if (Objects.isNull(member)) {
            MemberEntity memberEntity = new MemberEntity();

            memberEntity.setUsername(to.getUserName());
            memberEntity.setNickname(to.getUserName());
            memberEntity.setPassword(to.getPassword());
            memberEntity.setMobile(to.getPhone());

            memberEntity.setStatus(1);
            memberEntity.setCreateTime(new Date());

            MemberLevelEntity level = memberLevelService.getOne(Wrappers.<MemberLevelEntity>lambdaQuery()
                    .eq(MemberLevelEntity::getDefaultStatus, 1));

            memberEntity.setLevelId(level.getId());
            memberEntity.setGrowth(0);
            memberEntity.setIntegration(0);
            memberEntity.setSourceType(SourceType.REG);
            this.save(memberEntity);

            return R.ok();
        }

        return R.error(VALID_REG_USER_EXCEPTION.getCode(), String.format(VALID_REG_USER_EXCEPTION.getMeg(), to.getUserName()));

    }

    @Override
    public MemberEntity login(UserLoginTo to) {

        //查询数据库进行校验
        return this.getOne(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getUsername, to.getUserName())
                .or().eq(MemberEntity::getMobile, to.getUserName()));

    }

    @Transactional
    @Override
    public MemberEntity oauth2GiteeEnrollUser(GiteeUserInfoTo to) {
        try {
            GiteeResTo giteeResTo = to.getGiteeResTo();
            //查询如果存在就返回 不存在就保存
            MemberEntity member = this.getOne(Wrappers.<MemberEntity>lambdaQuery()
                    .eq(MemberEntity::getSocialUid, to.getId()));

            if (!Objects.isNull(member)) {
                //如果过期了 更新AccessToken
                if (StrUtil.isNotBlank(member.getExpiresIn()) && (System.currentTimeMillis() > Long.parseLong(member.getExpiresIn()))) {
                    String info = HttpUtil.post("https://gitee.com/oauth/token"
                            , Map.of("grant_type", "refresh_token",
                                    "refresh_token", member.getRefreshToken()));
                    giteeResTo = JSON.parseObject(info, GiteeResTo.class);
                    Calendar calendar = Calendar.getInstance();//new一个Calendar类,把Date放进去
                    calendar.setTime(new Date());
                    calendar.add(Calendar.DATE, 1);//实现日期加一操作,也就是明天
                    giteeResTo.setExpires_in(String.valueOf(calendar.getTime().getTime()));
                }

                member.setAccessToken(giteeResTo.getAccess_token());
                member.setExpiresIn(giteeResTo.getExpires_in());
                member.setRefreshToken(giteeResTo.getRefresh_token());
                member.setScope(giteeResTo.getScope());


                this.update(member, Wrappers.<MemberEntity>lambdaUpdate()
                        .eq(MemberEntity::getId, member.getId()));

                return member;
            }

            member = new MemberEntity();
            //查询是否存在同用户名
            MemberEntity member2 = this.getOne(Wrappers.<MemberEntity>lambdaQuery()
                    .eq(MemberEntity::getUsername, to.getLogin()));
            if (!Objects.isNull(member2)) {
                member.setUsername("gulimall_gitee" + to.getLogin() + "_" + UUID.randomUUID().toString().substring(0, 5));
            } else {
                member.setUsername("gulimall_gitee" + to.getLogin());
            }
            member.setPassword(new BCryptPasswordEncoder().encode("123456")); //初始密码 可以设置复杂随机数
            member.setNickname(to.getName());
            member.setEmail(to.getEmail());
            member.setHeader(to.getAvatar_url());
            member.setCreateTime(new Date());
            member.setStatus(1);
            MemberLevelEntity level = memberLevelService.getOne(Wrappers.<MemberLevelEntity>lambdaQuery()
                    .eq(MemberLevelEntity::getDefaultStatus, 1));
            member.setLevelId(level.getId());
            member.setGrowth(0);
            member.setIntegration(0);
            member.setSourceType(SourceType.GITEE);
            member.setAccessToken(giteeResTo.getAccess_token());
            member.setExpiresIn(giteeResTo.getExpires_in());
            member.setRefreshToken(giteeResTo.getRefresh_token());
            member.setScope(giteeResTo.getScope());
            member.setSocialUid(to.getId());
            this.save(member);

            return member;
        } catch (Exception e) {
            e.getStackTrace();
            log.error(e.getMessage());
            return null;
        }
    }

}